<?php
// @formatter:off
/**
 * @file WCGroupsHolder.php
 * @author Alejandro Dario Simi
 * @date $Date: 2013-06-07 02:16:25 +0000 (Fri, 07 Jun 2013) $
 *
 * $Id: WCGroupsHolder.php 71 2013-06-07 02:16:25Z daemonraco@gmail.com $
 * $URL: http://wcomix.googlecode.com/svn/tags/wcomix-1.0-BETA1/includes/holders/WCGroupsHolder.php $
 */
// @formatter:on

require_once "{$wcPaths["includes-directory"]}/representations/WCGroup.php";

/**
 * @class WCGroupsHolder
 */
class WCGroupsHolder {
	/**
	 * @var WCGroupsHolder
	 */
	protected static $_Instance;

	/**
	 * @var array()
	 */
	protected $_groups;
	/**
	 * @var array()
	 */
	protected $_groupsInverted;
	/**
	 * @var int
	 */
	protected $_time;
	/**
	 * @var PDO
	 */
	protected $_db;
	/**
	 * @var string
	 */
	protected $_dbprefix;

	protected function __construct() {
		global $wcDatabaseAccess;

		$this->_db = WCConnection::Instance();
		$this->_dbprefix = $wcDatabaseAccess['prefix'];

		$this->_groups = false;
		$this->_groupsInverted = false;
		$this->load();
	}
	public function __destruct() {
		unset($this->_groups);
		unset($this->_groupsInverted);
	}
	/**
	 * Prevent users to clone the instance.
	 */
	public function __clone() {
		trigger_error(__CLASS__.": Clone is not allowed.", E_USER_ERROR);
	}
	//
	// Public methods
	/**
	 * Creates a new group with default configurations
	 *
	 * @param string $name Name for the group.
	 * @param string $directory Root directory.
	 * @param string $trash Subdirectory where garbage has to be dropped.
	 * @return int Returns the id for the new group. On failure, returns false.
	 */
	public function add($name, $directory, $trash) {
		global $wcDirectoriesHolder;

		$id = false;

		$directory = WCSanitizer::SystemPath($directory);
		$trashPath = WCSanitizer::SystemPath("{$directory}{$trash}");
		if(is_dir($directory) && (!$trash || is_dir($trashPath))) {
			$query = "insert\n";
			$query .= "        into {$this->_dbprefix}groups (\n";
			$query .= "                grp_name, grp_root, grp_trash)\n";
			$query .= "        values (:name, :directory, :trash)\n";

			$stmt = $this->_db->prepare("WCGroupsHolder::add", $query);

			$params = array(
				":name" => $name,
				":directory" => $directory,
				":trash" => $trash
			);

			if($stmt->execute($params)) {
				$id = $this->_db->lastInsertId();
			}
		}
		//
		// Reloading all groups.
		$this->load();
		//
		// Adding first directory.
		if($id) {
			$dirname = "/";
			$group = $this->groupById($id);

			$wcDirectoriesHolder->create($dirname, $group);
		}
		//
		// Adding trash directory
		if($trash) {
			$group = $this->groupById($id);

			$wcDirectoriesHolder->create($trash, $group);
		}

		return $id;
	}
	public function countOfById($id) {
		if(isset($this->_groups[$id])) {
			return $this->_groups[$id]->count();
		} else {
			return false;
		}
	}
	public function countOfByName($name) {
		if(isset($this->_groupsInverted[$name])) {
			return $this->countOfById($this->_groupsInverted[$name]);
		} else {
			return false;
		}
	}
	public function db() {
		return $this->_db;
	}
	public function directoriesOfById($id) {
		if(isset($this->_groups[$id])) {
			return $this->_groups[$id]->directories();
		} else {
			return array();
		}
	}
	public function directoriesOfByName($name) {
		if(isset($this->_groupsInverted[$name])) {
			return $this->directoriesOfById($this->_groupsInverted[$name]);
		} else {
			return false;
		}
	}
	/**
	 * @param integer $id
	 * @return WCGroup
	 */
	public function groupById($id) {
		if(isset($this->_groups[$id])) {
			return $this->_groups[$id];
		} else {
			return false;
		}
	}
	/**
	 * @param string $name
	 * @return WCGroup
	 */
	public function groupByName($name) {
		if(isset($this->_groupsInverted[$name])) {
			return $this->groupById($this->_groupsInverted[$name]);
		} else {
			return null;
		}
	}
	public function groupId($name) {
		if(isset($this->_groupsInverted[$name])) {
			return $this->_groupsInverted[$name];
		} else {
			return null;
		}
	}
	public function groupIds() {
		return array_values($this->_groupsInverted);
	}
	public function groupName($id) {
		if(isset($this->_groups[$id])) {
			return $this->_groups[$id]->name();
		} else {
			return false;
		}
	}
	/**
	 * This methods allows to obtain all system configured groups.
	 *
	 * @return multitype:WCGroup List of loaded groups.
	 */
	public function & groups() {
		return $this->_groups;
	}
	public function reload() {
		return $this->load();
	}
	//
	// Protected methods
	protected function load() {
		$this->_groups = array();
		$this->_groupsInverted = array();

		$query = "select  grp_id,\n";
		$query .= "        grp_name\n";
		$query .= "from    {$this->_dbprefix}groups\n";
		$query .= "order by grp_name asc";

		$stmt = $this->_db->prepare("WCGroupsHolder::load", $query);

		if($stmt->execute(array())) {
			foreach($stmt->fetchAll() as $row) {
				$this->_groups[$row['grp_id']] = new WCGroup($this, $row['grp_id']);
				$this->_groupsInverted[$row['grp_name']] = $row['grp_id'];
			}
		}
	}
	//
	// Public class methods
	public static function Instance() {
		if(!isset(self::$_Instance)) {
			$c = __CLASS__;
			self::$_Instance = new $c();
		}

		return self::$_Instance;
	}
}
?>